package com.party.web.web.controller.wechatPlatform;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.party.common.constant.WechatConstant;
import com.party.common.utils.StringUtils;
import com.party.common.utils.refund.WechatPayUtils;
import com.party.core.model.member.DeployType;
import com.party.core.model.member.MemberExternalApp;
import com.party.core.model.wechatPlatform.WechatOpenMember;
import com.party.core.model.wechatPlatform.WechatOpenPlatform;
import com.party.core.service.member.IMemberExternalAppService;
import com.party.core.service.member.IThirdPartyUserService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.wechat.IWechatMessageService;
import com.party.core.service.wechat.IWechatSubscribeService;
import com.party.core.service.wechatPlatform.IWechatOpenMemberService;
import com.party.core.service.wechatPlatform.IWechatOpenPlatformService;
import com.party.web.biz.analysis.StatisticalEventFlowBizService;
import com.party.web.biz.circle.CircleBizNewService;
import com.party.web.biz.crowdfund.AnalyzeBizService;
import com.party.web.biz.crowdfund.ProjectBizService;
import com.party.web.biz.openPlatform.NotifyBizService;
import com.party.web.biz.photo.PhotoBizService;
import com.party.web.biz.sign.SignApplyBizService;
import com.party.web.biz.subject.SubjectBizService;
import com.party.web.biz.wechat.WechatBizService;
import com.party.web.utils.openPlatform.WXBizMsgCrypt;
import com.party.web.web.dto.input.wechatPlatform.ReceiveMsgInput;
import com.party.web.web.dto.input.wechatPlatform.ResolveMsgInput;
import com.party.web.web.dto.output.wechatPlatform.message.*;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 微信开放平台的第三方平台消息
 */
@Controller
@RequestMapping("/openPlatform/notify")
public class PlatformNotifyController {
    // 验证消息token
    @Value("#{wechat_platform['wechat.platform.token']}")
    private String token;

    // 消息加解密key
    @Value("#{wechat_platform['wechat.platform.encodingAesKey']}")
    private String encodingAesKey;

    @Value("#{wechat_platform['wechat.platform.appId']}")
    private String comAppId;

    @Autowired
    private NotifyBizService notifyBizService;

    @Autowired
    private IWechatOpenPlatformService wechatOpenPlatformService;

    @Autowired
    private IWechatMessageService wechatMessageService;

    @Autowired
    private IWechatOpenMemberService wechatOpenMemberService;

    @Autowired
    private WechatBizService wechatBizService;

    @Autowired
    private IWechatSubscribeService wechatSubscribeService;

    @Autowired
    private IMemberExternalAppService memberExternalAppService;

    @Autowired
    private StatisticalEventFlowBizService statisticalEventFlowBizService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IThirdPartyUserService thirdPartyUserService;

    @Autowired
    private ProjectBizService projectBizService;

    @Autowired
    private CircleBizNewService circleBizNewService;

    @Autowired
    private SignApplyBizService signApplyBizService;

    @Autowired
    private SubjectBizService subjectBizService;

    @Autowired
    private PhotoBizService photoBizService;

    @Autowired
    private AnalyzeBizService analyzeBizService;

    @Value("#{party['mic.url']}")
    private String micUrl;

    protected static Logger logger = LoggerFactory.getLogger(PlatformNotifyController.class);

    /**
     * 接收微信推送过来的消息
     *
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("receive")
    public void receiveNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.info("微信第三方平台---------微信推送Ticket消息10分钟一次-----------");
        String responseData = WechatPayUtils.getNotifyXml(request);
        try {
            logger.info("接收Ticket响应数据：{}", responseData);
            // 1.获取component_verify_ticket
            String componentVerifyTicket = notifyBizService.resolveTicket(token, encodingAesKey, responseData);

            List<WechatOpenPlatform> platforms = wechatOpenPlatformService.list(new WechatOpenPlatform());
            if (platforms.size() == 0) {
                WechatOpenPlatform platform = new WechatOpenPlatform();
                platform.setComponentVerifyTicket(componentVerifyTicket);
                wechatOpenPlatformService.insert(platform);
            } else {
                WechatOpenPlatform platform = platforms.get(0);
                platform.setComponentVerifyTicket(componentVerifyTicket);
                wechatOpenPlatformService.update(platform);
            }
        } catch (Exception e) {
            logger.error("微信推送Ticket接收异常：接收Ticket数据：" + responseData, e);
        } finally {
            response.getWriter().write("success");
            response.getWriter().close();
        }
    }


    /**
     * 接受微信服务的消息推送
     *
     * @param request 请求参数
     * @param appid   授权方appid
     * @return 处理结果
     */
    @ResponseBody
    @RequestMapping(value = "{appid}/receiveMsg")
    public void receiveMsg(HttpServletRequest request, @PathVariable String appid, ResolveMsgInput input, HttpServletResponse httpServletResponse) throws IOException {
//        appid = "wx4a3cd04f189325db";
//        input.setTimestamp("1536230997");
//        input.setMsg_signature("254a1a285d7f9a5b794f1f99a2e11236fd7f11df");
//        input.setNonce("730424623");
        long start = System.currentTimeMillis();
        logger.info("timestamp：{}，nonce：{}，msg_signature：{}", input.getTimestamp(), input.getNonce(), input.getMsg_signature());
        String response = WechatPayUtils.getNotifyXml(request);
//        String response = "<xml>    <ToUserName><![CDATA[gh_9bccc5eafcb3]]></ToUserName>    <Encrypt><![CDATA[CEL5y259A8Xzj5gsO13UV5EB1jXaZXvWqZfNYONdQ8cqhkJQjprJV7lldN+g5ndwMaxfTJAGd/QMOUTHBiDaIh5ItVx02h3/hOcgReH5JD3PowRpkcTKxhRJplG5MvUHPt5pOHN8tl9lMc+MS6nAGtj5H2JjqRRx7GV4URWCPOrV8y7xIM0xxGZWZhvgZ018n3HWXkncmYDE8iUr/6GwKs5lMn3ifKvRZyH5G8ub8wTZDcBkyCEeXTHizsYmxIre0RaHzW7FJduCrXTpDp3PhEj3J2U1b7ls4VCa04wtdb7Sj9i8NBk29SfUA+gM7SkhIzbnvteeHz98Lfgl8LLlpwuCYPjV19nyfe4nBFMkRiALiOXJeZrAfeQzEiFWXOm6SeD37MOAueBn57JxlC41mFu1xi6iJT3ICAfLghn7wnk=]]></Encrypt></xml>";
        logger.info("微信消息推送请求参数：{},appid：{}", response, appid);

        input.setToken(token);
        input.setAppId(comAppId);
        input.setEncodingAesKey(encodingAesKey);
        String message = "";
        try {
            WXBizMsgCrypt crypt = new WXBizMsgCrypt(input.getToken(), input.getEncodingAesKey(), input.getAppId());
            String decrypt = crypt.decryptMsg(input.getMsg_signature(), input.getTimestamp(), input.getNonce(), response);
            logger.info("解密结果：{}", decrypt);
            Map<String, String> decryptMap = WechatPayUtils.xmlToMap(decrypt);
            String responseXml = WechatPayUtils.mapToXml(decryptMap);

            ReceiveMsgInput receiveMsgInput = WechatPayUtils.xmlToBean(responseXml, ReceiveMsgInput.class);
            logger.info("xmlToBean结果：{}", JSONObject.toJSONString(receiveMsgInput));

            checkNotNull(receiveMsgInput, "消息内容不能为空");
            WechatOpenMember wechatOpenMember = wechatOpenMemberService.findByAppidAndDeployType(appid,
                    DeployType.AUTHORIZATION.getCode());



            String content = "";
            // 是否推送消息
            boolean sendMsg = true;
            // 是否图文消息
            boolean isImageText = false;
            Item item = null;
            // 是否图片消息
            boolean isImage = false;
            String mediaId = null;
            if (appid.equals("wx570bc396a51b8ff8")) {
                if (WechatConstant.REQ_MESSAGE_TYPE_TEXT.equals(receiveMsgInput.getMsgType())) {
                    //文本消息
                    if (StringUtils.startsWithIgnoreCase(receiveMsgInput.getContent(), "QUERY_AUTH_CODE")) {
                        content = "";
                        wechatBizService.replyApiMessage(receiveMsgInput.getContent().split(":")[1], receiveMsgInput.getFromUserName());
                    } else {
                        content = "TESTCOMPONENT_MSG_TYPE_TEXT_callback";
                    }
                } else if (WechatConstant.REQ_MESSAGE_TYPE_EVENT.equals(receiveMsgInput.getMsgType())) {
                    content = receiveMsgInput.getEvent() + "from_callback";
                }
            } else {
                if (null == wechatOpenMember) {
                    logger.error("商户未绑定——appid：" + appid);
                    return;
                }
                MemberExternalApp memberExternalApp
                        = memberExternalAppService.findByAppidAndDeployType(wechatOpenMember.getId(), DeployType.AUTHORIZATION.getCode());
                if (null == memberExternalApp) {
                    return;
                }
                if (WechatConstant.REQ_MESSAGE_TYPE_TEXT.equals(receiveMsgInput.getMsgType())) {
                    //文本消息
                    String reply = wechatMessageService.replyText(receiveMsgInput.getContent(), memberExternalApp.getMemberId());
                    content = reply == null ? content : reply;
                } else if (WechatConstant.REQ_MESSAGE_TYPE_EVENT.equals(receiveMsgInput.getMsgType())) {
                    //关注
                    if (WechatConstant.EVENT_TYPE_SUBSCRIBE.equals(receiveMsgInput.getEvent())) {
                        String reply
                                = wechatBizService.replyFocus(receiveMsgInput.getFromUserName(), memberExternalApp.getMemberId());
                        content = reply == null ? "欢迎关注！" : reply;
                        wechatSubscribeService.subscribe(appid, receiveMsgInput.getFromUserName());
//                        try {
//                            statisticalEventFlowBizService.focusSuccessEventWrite(receiveMsgInput.getFromUserName());
//                        } catch (BusinessException e) {
//                            logger.error("关注成功，写入关注成功事件流程异常", e);
//                        } catch (Exception e) {
//                            logger.error("关注成功，写入关注成功事件流程异常", e);
//                        }
                    }
                    // 取消关注
                    else if (WechatConstant.EVENT_TYPE_UNSUBSCRIBE.equals(receiveMsgInput.getEvent())) {
                        wechatSubscribeService.unSubscribe(appid, receiveMsgInput.getFromUserName());
                        analyzeBizService.updateSubscribe(receiveMsgInput.getFromUserName(), 0);
                        sendMsg = false;
                    }
                    // 扫描带参数二维码事件 用户已关注时的事件推送
                    else if (WechatConstant.EVENT_TYPE_SCAN.equals(receiveMsgInput.getEvent())) {
                        wechatSubscribeService.subscribe(appid, receiveMsgInput.getFromUserName());
                        analyzeBizService.updateSubscribe(receiveMsgInput.getFromUserName(), 1);
                        sendMsg = false;
                    }
                    // 自定义菜单事件 点击菜单拉取消息时的事件推送
                    else if (WechatConstant.EVENT_TYPE_CLICK.equals(receiveMsgInput.getEvent())) {
                        String eventKey = receiveMsgInput.getEventKey();
                        String myCrowdfund = sysConfigService.getMyCrowdfund();
                        String myCircle = sysConfigService.getMyCircle();
                        String mySign = sysConfigService.getMySign();
                        String myPhoto = sysConfigService.getMyPhoto();
                        String mySubject = sysConfigService.getMySubject();

                        String memberId = thirdPartyUserService.findByOpenId(receiveMsgInput.getFromUserName());
                        logger.info("{}对应的用户id为{}", receiveMsgInput.getFromUserName(), memberId);

                        // 我的众筹
                        if (StringUtils.isNotEmpty(myCrowdfund) && myCrowdfund.equals(eventKey)) {
                            // item = projectBizService.getItem(memberId);
                            String url = projectBizService.getReturnUrl(memberId);

                            item = new Item();
                            item.setTitle("我的众筹");
                            item.setDescription("问道八百里流沙，重走千年玄奘古路");

                            item.setPicUrl("http://tongxingzhe-10052192.file.myqcloud.com/wechat/official/my_crowdFunding.jpg");
                            item.setUrl(micUrl + url);
                            isImageText = true;
                        }
                        //
                        // 社交圈子
                        else if (StringUtils.isNotEmpty(myCircle) && myCircle.equals(eventKey)) {
                            String url = circleBizNewService.getReturnUrl(memberId);
/*                            StringBuilder sb = new StringBuilder("<a href=\"").append(micUrl + url).append("\">我加入的圈子</a>");
                            content = sb.toString();*/
                            item = new Item();
                            item.setTitle("社交圈子");
                            item.setDescription("结交天下志同道合者");

                            item.setPicUrl("http://tongxingzhe-10052192.file.myqcloud.com/wechat/official/circle.jpg");
                            item.setUrl(micUrl + url);
                            isImageText = true;
                        }
                        // 行走画押
                        else if (StringUtils.isNotEmpty(mySign) && mySign.equals(eventKey)) {
                            Map<String, String> resultMap = signApplyBizService.getReturnUrl(memberId);
                            String type = resultMap.get("type");
                            String value = resultMap.get("value");
                            if (type.equals("url")) { // 列表，发送文本消息
/*                                StringBuilder sb = new StringBuilder("<a href=\"").append(micUrl + value).append("\">我参加的打卡活动</a>");
                                content = sb.toString();*/
                                item = new Item();
                                item.setTitle("行走画押");
                                item.setDescription("你的坚持，终将美好");

                                item.setPicUrl("http://tongxingzhe-10052192.file.myqcloud.com/wechat/official/clockIn.jpg");
                                item.setUrl(micUrl + value);
                                isImageText = true;
                            } else if (type.equals("image")) { // 单个，发送图片消息
                                isImage = true;
                                mediaId = signApplyBizService.uploadTempMedia(value);
                            }
                        }
                        // 行者相册
                        else if (StringUtils.isNotEmpty(myPhoto) && myPhoto.equals(eventKey)) {
                            Map<String, String> resultMap = photoBizService.getReturnUrl(memberId);
                            String type = resultMap.get("type");
                            String value = resultMap.get("value");
                            if (type.equals("url")) { // 列表，发送文本消息
/*                                StringBuilder sb = new StringBuilder("<a href=\"").append(micUrl + value).append("\">我的相册</a>");
                                content = sb.toString();*/
                                item = new Item();
                                item.setTitle("行者相册");
                                item.setDescription("图记戈壁，收罗乐趣");

                                item.setPicUrl("http://tongxingzhe-10052192.file.myqcloud.com/wechat/official/xz_photo.jpg");
                                item.setUrl(micUrl + value);
                                isImageText = true;
                            } else if (type.equals("image")) { // 单个，发送图片消息
                                isImage = true;
                                mediaId = photoBizService.uploadTempMedia(value);
                            }
                        }
                        // 手机官网
                        else if (StringUtils.isNotEmpty(mySubject) && mySubject.equals(eventKey)) {
                            String url = subjectBizService.getReturnUrl(memberId);
/*                            StringBuilder sb = new StringBuilder("<a href=\"").append(micUrl + url).append("\">我的手机官网</a>");
                            content = sb.toString();*/
                            item = new Item();
                            item.setTitle("手机官网");
                            item.setDescription("一切尽在“手掌”中");
                            item.setPicUrl("http://tongxingzhe-10052192.file.myqcloud.com/wechat/official/phone_website.jpg");
                            item.setUrl(micUrl + url);
                            isImageText = true;
                        }
                        // 其他
                        else {
                            String reply = wechatMessageService.replyMenu(receiveMsgInput.getEventKey(), memberExternalApp.getMemberId());
                            content = reply == null ? content : reply;
                        }
                    }
                    // 自定义菜单事件 点击菜单跳转链接时的事件推送
                    else if (WechatConstant.EVENT_TYPE_VIEW.equals(receiveMsgInput.getEvent())) {
                        sendMsg = false;
                    }
                    // 上报地理位置事件
                    else if (WechatConstant.EVENT_TYPE_LOCATION.equals(receiveMsgInput.getEvent())) {
                        sendMsg = false;
                    }
                }
            }

            if (sendMsg && !isImageText && !isImage) { // 文本消息
                Long timeStamp = System.currentTimeMillis();
                TextMessage textMessage = new TextMessage();
                textMessage.setToUserName(receiveMsgInput.getFromUserName());
                textMessage.setFromUserName(receiveMsgInput.getToUserName());
                textMessage.setMsgType(WechatConstant.REQ_MESSAGE_TYPE_TEXT);
                textMessage.setCreateTime(timeStamp);
                textMessage.setContent(content);
                logger.info("待加密报文{}", WechatPayUtils.beanToXml(textMessage));

                message = notifyBizService.encryptMsg(WechatPayUtils.beanToXml(textMessage), input);
                if("".equals(content)){
                    message="success";
                }
                logger.info("加密后报文{}", message);
            } else if (sendMsg && isImageText && null != item) { // 图文消息
                Long timeStamp = System.currentTimeMillis();
                ArticleMessage articleMessage = new ArticleMessage();
                articleMessage.setToUserName(receiveMsgInput.getFromUserName());
                articleMessage.setFromUserName(receiveMsgInput.getToUserName());
                articleMessage.setMsgType(WechatConstant.RESP_MESSAGE_TYPE_NEWS);
                articleMessage.setCreateTime(timeStamp);
                articleMessage.setArticleCount("1");

                List<Item> items = Lists.newArrayList();
                items.add(item);

                articleMessage.setArticles(items);

                logger.info("待加密报文{}", WechatPayUtils.beanToXml(articleMessage));

                message = notifyBizService.encryptMsg(WechatPayUtils.beanToXml(articleMessage), input);
                logger.info("加密后报文{}", message);
            } else if (sendMsg && isImage && StringUtils.isNotEmpty(mediaId)) { // 图片消息
                Long timeStamp = System.currentTimeMillis();
                ImageMessage imageMessage = new ImageMessage();
                imageMessage.setToUserName(receiveMsgInput.getFromUserName());
                imageMessage.setFromUserName(receiveMsgInput.getToUserName());
                imageMessage.setMsgType(WechatConstant.REQ_MESSAGE_TYPE_IMAGE);
                imageMessage.setCreateTime(timeStamp);

                Image image = new Image();
                image.setMediaId(mediaId);
                imageMessage.setImage(image);
                logger.info("待加密报文{}", WechatPayUtils.beanToXml(imageMessage));

                message = notifyBizService.encryptMsg(WechatPayUtils.beanToXml(imageMessage), input);
            }
        } catch (Exception e) {
            logger.error("消息回复异常", e);
        }

        httpServletResponse.getWriter().write(message);
        httpServletResponse.getWriter().close();
        long end = System.currentTimeMillis();
        logger.info("appid：{},接收微信推送过来的消息执行时间：{}", appid, (end-start));
    }
}
